package com.itheima.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itheima.domain.User;
import com.itheima.domain.VO;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author ZhangyiA
 * @describe:
 * @date 2021/06/23
 */

@Controller
@RequestMapping("/user")
public class UserController {

    // 请求地址 http://localhost:8080/user/quick
    // @RequestMapping(value = "/quick")
    // 请求地址 http://localhost:8080/user/quick?username=xxx
    @RequestMapping(value = "/quick" , method = RequestMethod.GET , params = {"username"})  // 请求方式 , 即参数
    public String save(){
        System.out.println("UserController : running save");
        return "success";
    }

    @RequestMapping(value = "/quick2")
    public ModelAndView save2(){

        //------------------------视图跳转-------------------------------

        /*
        *  Model : 模型 作用封装数据
        *  View : 视图 作用展示数据
        * */
        ModelAndView modelAndView = new ModelAndView();
        // 设置模型数据
        modelAndView.addObject("username" , "itcast");
        // 设置视图名称
        modelAndView.setViewName("success");
        return  modelAndView;
    }

    // 相对于 save2 , SpringMVC 会自动注入 ,
    @RequestMapping(value = "/quick3")
    public ModelAndView save3(ModelAndView modelAndView){
        modelAndView.addObject("username" , "itheima");
        modelAndView.setViewName("success");
        System.out.println("sdfsdfsd");
        return modelAndView;
    }

    @RequestMapping(value = "/quick4")
    public String save4(Model model){
        model.addAttribute("username" , "博学谷");
        return "success";
    }

    // 不常用
    @RequestMapping(value = "/quick5")
    public String save5(HttpServletRequest request){
        request.setAttribute("username" , "ZhangyiA");
        return "success";
    }

    // -------------------------回写数据----------------------------

    @RequestMapping(value = "/quick6")
    public void save6(HttpServletResponse response) throws IOException {
        response.getWriter().print("hello itheima");
    }

    @RequestMapping(value = "/quick7")
    @ResponseBody // 告诉 SpringMVC 框架 , 该方法不进行页面跳转, 而是直接进行数据展示
    public String save7() {
        return "hello itheima";
    }

    @RequestMapping(value = "/quick8")
    @ResponseBody // 告诉 SpringMVC 框架 , 该方法不进行页面跳转, 而是直接进行数据展示
    public String save8() {
        return "{\"username\":\"ZhangyiA\" , \"age\":\"18\"}";
    }

    //  http://localhost:8080/user/quick9
    @RequestMapping(value = "/quick9")
    @ResponseBody // 告诉 SpringMVC 框架 , 该方法不进行页面跳转, 而是直接进行数据展示
    public String save9() throws JsonProcessingException {
        User user = new User();
        user.setAge(18);
        user.setUsername("ZhangyiA");
        // 使用 json 的转换工具，将对象转换成 json 字符串格式返回
        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(user);
        return json;
    }

    //  http://localhost:8080/user/quick10
    @RequestMapping(value = "/quick10")
    @ResponseBody // 告诉 SpringMVC 框架 , 该方法不进行页面跳转, 而是直接进行数据展示
    // 期望 StringMVC 自动将 User 转换成 json 格式的字符串
    public User save10() {
        User user = new User();
        user.setAge(19);
        user.setUsername("ZhangyiA1");
        return user;
    }

    @RequestMapping(value = "/quick11")
    @ResponseBody
    // 请求地址 http://localhost:8080/user/quick11?username=ZhangyiA&age=20
    public void save11(String username , int age) {
        System.out.println(username + "  " + age);  // ZhangyiA  20
    }

    @RequestMapping(value = "/quick12")
    @ResponseBody
    // 请求地址 http://localhost:8080/user/quick11?username=ZhangyiA&age=20
    public void save12(User user) { // 上面 save11 还可以直接将数据封装到 User 对象中, 前提是 User 类中有和请求参数具有相同的属性 username 和 age 属性
        System.out.println(user.toString());  // ZhangyiA  20
    }

    @RequestMapping(value = "/quick14")
    @ResponseBody
    // 请求地址 http://localhost:8080/jsp/form.jsp
    // 先通过 表单填写 请求参数
    // 提交 集合 参数
    // 封装到 VO 对象中
    public void save14(VO vo) { // 上面 save11 还可以直接将数据封装到 User 对象中, 前提是 User 类中有和请求参数具有相同的属性 username 和 age 属性
        System.out.println(vo);
    }

    @RequestMapping(value = "/quick15")
    @ResponseBody
    public void save15(@RequestBody List<User> userList) { // 将请求体直接封装到实体 VO 集合中 , 也就是必须先有 VO 类 中有 List<User> 集合
        System.out.println(userList);
    }

    // 开发当中常用
    @RequestMapping(value = "/quick16")
    @ResponseBody
    // 请求地址 http://localhost:8080/user/quick16?name=ZhangyiA  返回 ZhangyiA
    // 当请求的 参数 和 已定义的不一致时 可通过 @RequestParam 进行映射 , 加上 required 时 参数不写也不会报错
    // defaultValue 当没有指定请求参数时 , 则使用指定的默认值赋值
    // 请求地址 http://localhost:8080/user/quick16 返回 admin
    public void save16(@RequestParam(value = "name" , required = false , defaultValue = "admin") String username) {
        System.out.println(username);
    }

    // ------------------------------Restful 风格参数-------------------------------

    // 请求地址  http://localhost:8080/user/quick17/zhaosi
    @RequestMapping(value = "/quick17/{username}")
    @ResponseBody
    public void save17(@PathVariable(value = "username") String username) {
        System.out.println(username);
    }

    // -----------------自定义类型转换器（开发中用的不多，需要转回类型时在转）-------------
    // 配置过程 1. 定义转换器类 实现 Converter 接口
    //         2. 在配置文件中申明转换器
    //         3. 在 <mvc:annotation-driven conversion-service="conversionService"/> 中引用转换器

    // 请求地址 http://localhost:8080/user/quick18?date=1996-02-20

    @RequestMapping(value = "/quick18")
    @ResponseBody
    public void save18(Date date) {
        System.out.println(date);
    }

    // --------------------------------获取请求头 @RequestHeader ----------------------------------
    // 请求地址 ： http://localhost:8080/user/quick19

    @RequestMapping(value = "/quick19")
    @ResponseBody
    public void save19(@RequestHeader(value = "User-Agent" , required = false) String user_agent) {
        System.out.println(user_agent);

    }

    @RequestMapping(value = "/quick20")
    @ResponseBody
    public void save20(@CookieValue(value = "JSESSIONID") String jsessionId) {
        System.out.println(jsessionId);
    }

    //-------------------------------文件上传--------------------------------------------
    // 请求地址 ： http://localhost:8080/jsp/upload.jsp

    @RequestMapping(value = "/quick21")
    @ResponseBody
    // 方法参数名称必须和表单的名称一致
    // 表单中文件参数名称不一样
    public void save21(String username , MultipartFile uploadFile , MultipartFile uploadFile2) throws IOException {
        System.out.println(username);
        String fileName = uploadFile.getOriginalFilename();
        uploadFile.transferTo(new File("D:\\upload\\" + fileName)); // 需要给定出了 fileName 的具体文件夹路径
        String fileName2 = uploadFile2.getOriginalFilename();
        uploadFile2.transferTo(new File("D:\\upload\\" + fileName2)); // 需要给定出了 fileName 的具体文件夹路径
    }

    @RequestMapping(value = "/quick22")
    @ResponseBody
    // 方法参数名称必须和表单的名称一致
    // 表单中文件参数名称一样 uploadFile , 此时需要用数组接收
    public void save22(String username , MultipartFile[] uploadFile) throws IOException {
        System.out.println(username);
        for(MultipartFile file : uploadFile){
            String fileName = file.getOriginalFilename();
            file.transferTo(new File("D:\\upload\\" + fileName));
        }
    }

}
